package com.yxyc.rainbow.common.base;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.enums.SqlLike;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.IService;
import com.yxyc.rainbow.common.response.ObjectRestResponse;
import com.yxyc.rainbow.common.response.TableResultResponse;
import com.yxyc.rainbow.common.util.EntityUtils;
import com.yxyc.rainbow.common.util.PageInfoBT;
import com.yxyc.rainbow.common.util.pageplus.Query;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.lang.reflect.ParameterizedType;
import java.util.List;
import java.util.Map;

/**
 * ┏┓　　　┏┓
 * ┏┛┻━━━┛┻┓
 * ┃　　　　　　　┃
 * ┃　　　━　　　┃
 * ┃　┳┛　┗┳　┃
 * ┃　　　　　　　┃
 * ┃　　　┻　　　┃
 * ┃　　　　　　　┃
 * ┗━┓　　　┏━┛
 * 　　┃　　　┃神兽保佑
 * 　　┃　　　┃代码无BUG！
 * 　　┃　　　┗━━━┓
 * 　　┃　　　　　　　┣┓
 * 　　┃　　　　　　　┏┛
 * 　　┗┓┓┏━┳┓┏┛
 * 　　　┃┫┫　┃┫┫
 * 　　　┗┻┛　┗┻┛
 *
 * @author yeoman
 * @description
 * @create 2018/8/26 16:52
 **/
public class BaseController<Service extends IService, Entity> {
    @Autowired
    protected Service service;

    /**
     * 把service层的分页信息，封装为bootstrap table通用的分页封装
     */
    protected <T> PageInfoBT<T> packForBT(Page<T> page) {
        return new PageInfoBT<T>(page);
    }

    @PostMapping(value = "")
    @ApiOperation("新增单个对象")
    public ObjectRestResponse<Entity> add(@RequestBody JSONObject objs) {
        Class<Entity> clazz = (Class<Entity>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[1];
        Entity entity = objs.toJavaObject(clazz);
        EntityUtils.setCreatAndUpdatInfo(entity);
        // 用户名和密码需要加密后保存
        service.insert(entity);
        return new ObjectRestResponse<Entity>();
    }

    @GetMapping(value = "/{id}")
    @ApiOperation("查询单个对象")
    public ObjectRestResponse<Entity> get(@PathVariable int id) {
        ObjectRestResponse<Entity> entityObjectRestResponse = new ObjectRestResponse<>();
        Object o = service.selectById(id);
        entityObjectRestResponse.data((Entity) o);
        return entityObjectRestResponse;
    }

    @PutMapping(value = "/{id}")
    @ApiOperation("更新单个对象")
    public ObjectRestResponse<Entity> update(@RequestBody JSONObject objs) {
        Class<Entity> clazz = (Class<Entity>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[1];
        Entity entity = objs.toJavaObject(clazz);
        EntityUtils.setUpdatedInfo(entity);
        service.updateById(entity);
        return new ObjectRestResponse<Entity>();
    }

    @DeleteMapping(value = "/{id}")
    @ApiOperation("移除单个对象")
    public ObjectRestResponse<Entity> remove(@PathVariable int id) {
        service.deleteById(id);
        return new ObjectRestResponse<Entity>();
    }


    public String getCurrentUserName() {
        return BaseContextHandler.getUsername();
    }

    /**
     * 公共分页接口，支持模糊查询分页
     *
     * @param params
     * @return
     */
    @GetMapping(value = "/page")
    @ApiOperation("分页获取数据")
    public TableResultResponse<Entity> list(@RequestParam Map<String, Object> params) {
        Class<Entity> clazz = (Class<Entity>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[1];
        Query query = new Query<Entity>(params);
        EntityWrapper ew = new EntityWrapper();
        if (query.entrySet().size() > 0) {
            for (Object entry : query.entrySet()) {
                Map.Entry<String, Object> mapEntry = (Map.Entry<String, Object>) entry;
                if (!"page".equals(mapEntry.getKey())) {
                    ew.like(mapEntry.getKey(), mapEntry.getValue().toString(), SqlLike.DEFAULT);
                }
            }
        }
        Page<Entity> page = service.selectPage(query.getPage(), ew);

        return new TableResultResponse<Entity>(page.getTotal(), page.getRecords());
    }

    /**
     * 查询所有数据
     *
     * @return
     */
    @GetMapping(value = "/all")
    @ApiOperation("获取所有数据")
    public List<Entity> all() {
        return service.selectList(null);
    }
}
